home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / filesyst / ncpfs / mars_dos.000 / mars_dos / netpc / nwcrypt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-22  |  9.1 KB  |  340 lines

  1. /*$*********************************************************
  2. $*
  3. $* This code has been taken from DDJ 11/93, from an
  4. $* article by Pawel Szczerbina.
  5. $*
  6. $* Password encryption routines follow.
  7. $* Converted to C from Barry Nance's Pascal
  8. $* prog published in the March -93 issue of Byte.
  9. $*
  10. $* Adapted to be useable for ncpfs by
  11. $* Volker Lendecke <lendecke@namu01.gwdg.de> in
  12. $* October 1995.
  13. $*
  14. $* Stolen to be useable for mars_nwe by
  15. $* Martin Stover <mstover@freeway.de> in
  16. $* Dezember 1995.
  17. $**********************************************************/
  18.  
  19. /****************************************************************************
  20.  
  21. I read that Novell is not very open when it comes to technical details
  22. of the Netware Core Protocol. This might be especially true for the
  23. encryption stuff. I took the necessary code from Dr. Dobb's Journal
  24. 11/93, Undocumented Corner. I asked Jon Erickson <jon@ddj.com> about
  25. the legal status of this piece of code:
  26.  
  27.  
  28. ---
  29. Date: Thu, 12 Oct 1995 13:44:18 +0100
  30. From: Volker Lendecke <lendecke>
  31. To: jon@ddj.com
  32. Subject: legal status of your source code?
  33.  
  34.  
  35. Hello!
  36.  
  37. I hope that you're the right one to write to, you are the first on your WWW
  38. server. If you are not, could you please forward this message to the right
  39. person? Thanks.
  40.  
  41. I'm currently exploring the possibility to write a free (in the GNU GPL
  42. sense) NCP filesystem, which would allow me to access a novell server
  43. transparently. For that I would like to use the encryption functions you
  44. published in DDJ 11/93, Undocumented Corner. I would make some cosmetic
  45. changes, such as other indentations, minor code changes and so on. But I do
  46. not know if that allows me to publish this code under GPL. One alternative
  47. would be to publish a diff against your listing, but that would probably
  48. contain much of your code as well, and it would be very inconvenient for
  49. the average user.
  50.  
  51. I think that you have some kind of standard procedure for such a
  52. case. Please tell me what I should do.
  53.  
  54. Many thanks in advance,
  55.  
  56.     Volker
  57.  
  58.    +=================================================================+
  59.    ! Volker Lendecke               Internet: lendecke@namu01.gwdg.de !
  60.    ! D-37081 Goettingen, Germany                                     !
  61.    +=================================================================+
  62.  
  63. --
  64.  
  65.  
  66. I got the following answer:
  67.  
  68. ---
  69. From: Jon Erickson <jon@ddj.com>
  70. X-Mailer: SCO System V Mail (version 3.2)
  71. To: lendecke@namu01.gwdg.de
  72. Subject: Re: legal status of your source code?
  73. Date: Thu, 12 Oct 95 5:42:56 PDT
  74.  
  75. Volker,
  76. Code from Dr. Dobb's Journal related articles is provided for
  77. anyone to use. Clearly, the author of the article should be
  78. given credit.
  79. Jon Erickson
  80.  
  81. ---
  82.  
  83. With this answer in mind, I took the code and made it a bit more
  84. C-like. The original seemed to be translated by a mechanical pascal->c
  85. translator. Jon's answer encouraged me to publish nwcrypt.c under the
  86. GPL. If anybody who knows more about copyright and sees any problems
  87. with this, please tell me.
  88. ****************************************************************************/
  89.  
  90. /******************* Data types ***************************/
  91. typedef unsigned char buf32[32];
  92. typedef unsigned char buf16[16];
  93. typedef unsigned char buf8[8];
  94. typedef unsigned char buf4[4];
  95. typedef unsigned char u8;
  96.  
  97. static u8 encrypttable[256] =
  98. {0x7,0x8,0x0,0x8,0x6,0x4,0xE,0x4,0x5,0xC,0x1,0x7,0xB,0xF,0xA,0x8,
  99.  0xF,0x8,0xC,0xC,0x9,0x4,0x1,0xE,0x4,0x6,0x2,0x4,0x0,0xA,0xB,0x9,
  100.  0x2,0xF,0xB,0x1,0xD,0x2,0x1,0x9,0x5,0xE,0x7,0x0,0x0,0x2,0x6,0x6,
  101.  0x0,0x7,0x3,0x8,0x2,0x9,0x3,0xF,0x7,0xF,0xC,0xF,0x6,0x4,0xA,0x0,
  102.  0x2,0x3,0xA,0xB,0xD,0x8,0x3,0xA,0x1,0x7,0xC,0xF,0x1,0x8,0x9,0xD,
  103.  0x9,0x1,0x9,0x4,0xE,0x4,0xC,0x5,0x5,0xC,0x8,0xB,0x2,0x3,0x9,0xE,
  104.  0x7,0x7,0x6,0x9,0xE,0xF,0xC,0x8,0xD,0x1,0xA,0x6,0xE,0xD,0x0,0x7,
  105.  0x7,0xA,0x0,0x1,0xF,0x5,0x4,0xB,0x7,0xB,0xE,0xC,0x9,0x5,0xD,0x1,
  106.  0xB,0xD,0x1,0x3,0x5,0xD,0xE,0x6,0x3,0x0,0xB,0xB,0xF,0x3,0x6,0x4,
  107.  0x9,0xD,0xA,0x3,0x1,0x4,0x9,0x4,0x8,0x3,0xB,0xE,0x5,0x0,0x5,0x2,
  108.  0xC,0xB,0xD,0x5,0xD,0x5,0xD,0x2,0xD,0x9,0xA,0xC,0xA,0x0,0xB,0x3,
  109.  0x5,0x3,0x6,0x9,0x5,0x1,0xE,0xE,0x0,0xE,0x8,0x2,0xD,0x2,0x2,0x0,
  110.  0x4,0xF,0x8,0x5,0x9,0x6,0x8,0x6,0xB,0xA,0xB,0xF,0x0,0x7,0x2,0x8,
  111.  0xC,0x7,0x3,0xA,0x1,0x4,0x2,0x5,0xF,0x7,0xA,0xC,0xE,0x5,0x9,0x3,
  112.  0xE,0x7,0x1,0x2,0xE,0x1,0xF,0x4,0xA,0x6,0xC,0x6,0xF,0x4,0x3,0x0,
  113.  0xC,0x0,0x3,0x6,0xF,0x8,0x7,0xB,0x2,0xD,0xC,0x6,0xA,0xA,0x8,0xD};
  114.  
  115. static buf32 encryptkeys  =
  116. {0x48,0x93,0x46,0x67,0x98,0x3D,0xE6,0x8D,
  117.  0xB7,0x10,0x7A,0x26,0x5A,0xB9,0xB1,0x35,
  118.  0x6B,0x0F,0xD5,0x70,0xAE,0xFB,0xAD,0x11,
  119.  0xF4,0x47,0xDC,0xA7,0xEC,0xCF,0x50,0xC0};
  120.  
  121. #include "nwcrypt.h"
  122. static void
  123. shuffle1(buf32 temp, unsigned char *target)
  124. {
  125.     short b4;
  126.     unsigned char b3;
  127.     int s, b2, i;
  128.  
  129.     b4 = 0;
  130.  
  131.     for (b2 = 0; b2 <= 1; ++b2)
  132.     {
  133.         for (s = 0; s <= 31; ++s)
  134.         {
  135.             b3 = (temp[s]+b4) ^ (temp[(s+b4)&31] - encryptkeys[s]);
  136.             b4 = b4 + b3;
  137.             temp[s] = b3;
  138.         }
  139.     }
  140.  
  141.     for (i = 0; i <= 15; ++i) {
  142.         target[i] =    encrypttable[temp[ 2*i    ]]
  143.                 | (encrypttable[temp[ 2*i + 1]] << 4);
  144.     }
  145. }
  146.  
  147.  
  148. void
  149. shuffle(unsigned char *lon, const unsigned char *buf, int buflen,
  150.     unsigned char *target)
  151. {
  152.     int b2, d, s;
  153.     buf32 temp;
  154.  
  155.     while (   (buflen > 0)
  156.            && (buf[buflen - 1] == 0)) {
  157.         buflen = buflen - 1;
  158.     }
  159.  
  160.     for (s = 0; s < 32; s++) {
  161.         temp[s] = 0;
  162.     }
  163.  
  164.     d = 0;
  165.     while (buflen >= 32)
  166.     {
  167.         for (s = 0; s <= 31; ++s)
  168.         {
  169.             temp[s] = temp[s] ^ buf[d];
  170.             d = d + 1;
  171.         }
  172.         buflen = buflen - 32;
  173.     }
  174.     b2 = d;
  175.     if (buflen > 0)
  176.     {
  177.         for (s = 0; s <= 31; ++s)
  178.         {
  179.             if (d + buflen == b2)
  180.             {
  181.                 b2 = d;
  182.                 temp[s] = temp[s] ^ encryptkeys[s];
  183.             } else {
  184.                 temp[s] = temp[s] ^ buf[b2];
  185.                 b2 = b2 + 1;
  186.             }
  187.         }
  188.     }
  189.  
  190.     for (s = 0; s <= 31; ++s)
  191.         temp[s] = temp[s] ^ lon[s & 3];
  192.  
  193.     shuffle1(temp,target);
  194. }
  195.  
  196.  
  197. void
  198. nw_encrypt(unsigned char *fra,unsigned char *buf,unsigned char *til)
  199. {
  200.     buf32 k;
  201.     int s;
  202.  
  203.     shuffle(&(fra[0]), buf, 16, &(k[ 0]));
  204.     shuffle(&(fra[4]), buf, 16, &(k[16]));
  205.  
  206.     for (s = 0; s <= 15; ++s)
  207.         k[s] = k[s] ^ k[31 - s];
  208.  
  209.     for (s = 0; s <= 7; ++s)
  210.         til[s] = k[s] ^ k[15 - s];
  211. }
  212.  
  213.  
  214. /* =========== next is from Guntram Blohm ! =============== */
  215. static char newshuffle[256+16] = {
  216.     0x0f, 0x08, 0x05, 0x07, 0x0c, 0x02, 0x0e, 0x09,
  217.     0x00, 0x01, 0x06, 0x0d, 0x03, 0x04, 0x0b, 0x0a,
  218.     0x02, 0x0c, 0x0e, 0x06, 0x0f, 0x00, 0x01, 0x08,
  219.     0x0d, 0x03, 0x0a, 0x04, 0x09, 0x0b, 0x05, 0x07,
  220.  
  221.     0x05, 0x02, 0x09, 0x0f, 0x0c, 0x04, 0x0d, 0x00,
  222.     0x0e, 0x0a, 0x06, 0x08, 0x0b, 0x01, 0x03, 0x07,
  223.     0x0f, 0x0d, 0x02, 0x06, 0x07, 0x08, 0x05, 0x09,
  224.     0x00, 0x04, 0x0c, 0x03, 0x01, 0x0a, 0x0b, 0x0e,
  225.  
  226.     0x05, 0x0e, 0x02, 0x0b, 0x0d, 0x0a, 0x07, 0x00,
  227.     0x08, 0x06, 0x04, 0x01, 0x0f, 0x0c, 0x03, 0x09,
  228.     0x08, 0x02, 0x0f, 0x0a, 0x05, 0x09, 0x06, 0x0c,
  229.     0x00, 0x0b, 0x01, 0x0d, 0x07, 0x03, 0x04, 0x0e,
  230.  
  231.     0x0e, 0x08, 0x00, 0x09, 0x04, 0x0b, 0x02, 0x07,
  232.     0x0c, 0x03, 0x0a, 0x05, 0x0d, 0x01, 0x06, 0x0f,
  233.     0x01, 0x04, 0x08, 0x0a, 0x0d, 0x0b, 0x07, 0x0e,
  234.     0x05, 0x0f, 0x03, 0x09, 0x00, 0x02, 0x06, 0x0c,
  235.  
  236.     0x05, 0x03, 0x0c, 0x08, 0x0b, 0x02, 0x0e, 0x0a,
  237.     0x04, 0x01, 0x0d, 0x00, 0x06, 0x07, 0x0f, 0x09,
  238.     0x06, 0x00, 0x0b, 0x0e, 0x0d, 0x04, 0x0c, 0x0f,
  239.     0x07, 0x02, 0x08, 0x0a, 0x01, 0x05, 0x03, 0x09,
  240.  
  241.     0x0b, 0x05, 0x0a, 0x0e, 0x0f, 0x01, 0x0c, 0x00,
  242.     0x06, 0x04, 0x02, 0x09, 0x03, 0x0d, 0x07, 0x08,
  243.     0x07, 0x02, 0x0a, 0x00, 0x0e, 0x08, 0x0f, 0x04,
  244.     0x0c, 0x0b, 0x09, 0x01, 0x05, 0x0d, 0x03, 0x06,
  245.  
  246.     0x07, 0x04, 0x0f, 0x09, 0x05, 0x01, 0x0c, 0x0b,
  247.     0x00, 0x03, 0x08, 0x0e, 0x02, 0x0a, 0x06, 0x0d,
  248.     0x09, 0x04, 0x08, 0x00, 0x0a, 0x03, 0x01, 0x0c,
  249.     0x05, 0x0f, 0x07, 0x02, 0x0b, 0x0e, 0x06, 0x0d,
  250.  
  251.     0x09, 0x05, 0x04, 0x07, 0x0e, 0x08, 0x03, 0x01,
  252.     0x0d, 0x0b, 0x0c, 0x02, 0x00, 0x0f, 0x06, 0x0a,
  253.     0x09, 0x0a, 0x0b, 0x0d, 0x05, 0x03, 0x0f, 0x00,
  254.     0x01, 0x0c, 0x08, 0x07, 0x06, 0x04, 0x0e, 0x02,
  255.  
  256.     0x03, 0x0e, 0x0f, 0x02, 0x0d, 0x0c, 0x04, 0x05,
  257.     0x09, 0x06, 0x00, 0x01, 0x0b, 0x07, 0x0a, 0x08,
  258. };
  259.  
  260.  
  261. void nw_decrypt_newpass(char *oldpwd, char *newpwd, char *undecr)
  262. {
  263.     int i, j, n;
  264.     unsigned char ch, cl;
  265.  
  266.     char invshuffle[256+16];
  267.     char copy[8];
  268.  
  269.     for (i=0; i<256+16; i+=16)
  270.         for (j=0; j<16; j++)
  271.             invshuffle[i+newshuffle[i+j]]=j;
  272.  
  273.     for (i=0; i<16; i++)
  274.     {
  275.         memset(copy, '\0', 8);
  276.         for (j=0; j<16; j++)
  277.         {
  278.             n=newshuffle[j+0x100];
  279.  
  280.             ch=(j&1 ? (newpwd[j/2]>>4)&0x0f : newpwd[j/2]&0x0f);
  281.             copy[n/2]|=(n&1) ? (ch<<4) : ch;
  282.         }
  283.  
  284.         ch=(oldpwd[0]<<4);
  285.         for (j=0; j<7; j++)
  286.             oldpwd[j]=(oldpwd[j+1]<<4)|((oldpwd[j]>>4)&0x0f);
  287.         oldpwd[7]=ch|((oldpwd[7]>>4)&0x0f);
  288.  
  289.         for (j=0; j<8; j++)
  290.         {
  291.             cl=invshuffle[((copy[j]   )&0x0f)+j*32   ]   ;
  292.             ch=invshuffle[((copy[j]>>4)&0x0f)+j*32+16]<<4;
  293.             copy[j]=(ch|cl)^oldpwd[j];
  294.         }
  295.         memcpy(newpwd, copy, 8);
  296.     }
  297.     memcpy(undecr, copy, 8);
  298. }
  299.  
  300.  
  301. void newpassencrypt(char *old, char *new, char *out)
  302. {
  303.     char *p, *bx;
  304.     char copy[8];
  305.     int i, di, ax;
  306.     char cl, dl, ch;
  307.  
  308.     memcpy(copy, new, 8);
  309.  
  310.     for (i=0; i<16; i++)
  311.     {
  312.         for (di=0, ax=0, p=old; di<8; di++, ax+=0x20, p++)
  313.         {
  314.             cl=newshuffle[(((copy[di]^*p)>>4)&0x0f)+ax+0x10]<<4;
  315.             dl=newshuffle[((copy[di]^*p)&0xf)+ax];
  316.             copy[di]=cl|dl;
  317.         }
  318.  
  319.         ch=old[7];
  320.         for (bx=old+7; bx>old; bx--)
  321.         {
  322.             *bx=((bx[-1]>>4)&0x0f)|((*bx)<<4);
  323.         }
  324.         *old=((ch>>4)&0x0f)|(*old)<<4;
  325.  
  326.         memset(out, '\0', 8);
  327.  
  328.         for (di=0; di<16; di++)
  329.         {
  330.             if (newshuffle[di+0x100]&1)
  331.                 ch=((copy[newshuffle[di+0x100]/2]>>4)&0x0f);
  332.             else
  333.                 ch=copy[newshuffle[di+0x100]/2]&0x0f;
  334.             out[di/2]|=((di&1) ? ch<<4 : ch);
  335.         }
  336.         memcpy(copy, out, 8);
  337.     }
  338. }
  339.  
  340.